//! 设备管理接口

use std::sync::{Arc, Mutex};

use dfs::inode::DfsInode;
use error::{SmkError, SmkResult};

/// 设备接口返回结果
///
/// `SmkResult` 别名
pub type IfDevResult<T> = SmkResult<T>;

/// 设备接口错误代码
///
/// `SmkError` 别名
pub type IfDevError = SmkError;

/// 设备文件节点操作
pub use dfs;
use objectid::ObjectId;

/// 设备复位类型
pub enum DeviceResetType {
    /// 热复位
    Hot,
    /// 冷复位
    Cold,
}

/// 设备管理实现
#[allow(unused_variables)]
pub trait DeviceManageImpl: ObjectId {
    /// 设备实例化
    fn realize(&self) {}
    /// 设备热复位
    fn reset(&self, reset: DeviceResetType) {}
    /// 设备配置选项, 可选
    ///
    /// # Errors
    /// 由设备返回错误
    fn create_options(&self, path: Arc<DfsInode>) -> IfDevResult<()> {
        Ok(())
    }
    /// 设备配置选项结束, 可选
    ///
    /// # Errors
    /// 由设备返回错误
    fn create_options_end(&self, path: Arc<DfsInode>) -> IfDevResult<()> {
        Ok(())
    }
    /// 交互接口
    ///
    /// # Errors
    /// 由设备返回错误
    fn interactive(&self, path: Arc<DfsInode>) -> IfDevResult<()> {
        Ok(())
    }
}

static DEVICE_BOX: Mutex<Vec<Arc<dyn DeviceManageImpl + Send + Sync>>> = Mutex::new(Vec::new());

/// 注册一个设备到全局管理器中
#[allow(clippy::missing_panics_doc)]
pub fn register_device(dev: Arc<dyn DeviceManageImpl + Send + Sync>) {
    let mut lock = DEVICE_BOX.lock().unwrap();
    lock.push(dev);
}

/// 遍历当前 Map
#[allow(clippy::missing_panics_doc)]
pub fn device_for_each<F>(mut f: F)
where
    F: FnMut(&(dyn DeviceManageImpl + Send + Sync)),
{
    let lock = DEVICE_BOX.lock().unwrap();
    lock.iter().for_each(|dev| f(dev.as_ref()));
}
